package com.studyroom.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.studyroom.dto.ContactDTO;
import com.studyroom.dto.Mail;
import com.studyroom.dto.Result;
import com.studyroom.dto.UserDTO;
import com.studyroom.entity.RoomMember;
import com.studyroom.entity.User;
import com.studyroom.mapper.RoomMemberMapper;
import com.studyroom.mapper.UserMapper;
import com.studyroom.service.ContactService;
import com.studyroom.service.MailService;
import com.studyroom.utils.UserHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.time.LocalDateTime;
import java.util.*;

import static com.studyroom.utils.RedisContants.*;


@Service
public class ContactServiceImpl implements ContactService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private UserMapper userMapper;
    @Resource
    private RoomMemberMapper roomMemberMapper;
    @Resource
    private MailService mailService;


    @Override
    public Result getAll() {
        //获取当前用户信息
        UserDTO me=UserHolder.getUser ();
        //从数据查询我的好友
        List<User> users=userMapper.getUsersByUserIdWithUserRelation (me.getId ());
        //准备返回的好友信息List
        List<UserDTO> userDTOS=new ArrayList<> ();
        for(User user:users) {
            //复制属性
            UserDTO userDTO=BeanUtil.copyProperties (user,UserDTO.class);
           //获取当前好友在线信息
            String onlineKey = ONLINE_KEY + userDTO.getId ();
            Long count = stringRedisTemplate.getExpire (onlineKey);
            if (count < 0) {
                userDTO.setOnline (false);
            } else {
                //在线，设置是否在线
                userDTO.setOnline (true);
                //在线，获取好友在线时长
                String time=stringRedisTemplate.opsForValue ().get (onlineKey);
                //设置上线时间
                userDTO.setOnlineTime (LocalDateTime.parse (time));
            }
            //添加到要返回前端的数据
             userDTOS.add (userDTO);
        }
        return Result.ok (userDTOS);
    }

    @Override
    public Result sendRequest(Long id) {
        UserDTO me= UserHolder.getUser ();
        //查询对方是否是你的好友
        User user=userMapper.getUserByUserRealtion (me.getId (),id);
        if(user!=null){
            return Result.fail ("对方已经是你的好友");
        }
        //写入对方的好友请求信息到redis
        Result addContactRequestResult=addContactRequestByRedis(id,me.getId ());
        if(!addContactRequestResult.isSuccess ()){
            return addContactRequestResult;
        }
        return Result.ok ();
    }

    @Override
    public Result getRequest() {
        UserDTO me=UserHolder.getUser ();
        //从redis获取好友请求
        String key=CONTACTS_REQUEST_KEY+me.getId ();
        String json=stringRedisTemplate.opsForValue ().get (key);
        if(StrUtil.isBlank (json)){
            return Result.fail ("暂无请求");
        }
        List<UserDTO> contactRequestList=JSONUtil.toList (json,UserDTO.class);
        return Result.ok (contactRequestList);
    }

    @Override
    public Result consentRequest(Long id) {
        UserDTO me=UserHolder.getUser ();
        //删除好友请求
        this.delContactRequestByRedis (me.getId (),id);
        //对方是否已经是好友
        User user=userMapper.getUserByUserRealtion (me.getId (),id);
        if(user!=null){
            return Result.fail ("对方已经是你的好友");
        }
        this.saveRelationOnBoth (me.getId (),id);
        //发送mail通知对方用户
        Mail mail=new Mail (me.getId (),id,me.getUsername ()+"同意了你的好友请求",LocalDateTime.now ());
        mailService.send (mail);
        return Result.ok ();
    }
    //添加好友请求到redis方法
    private Result addContactRequestByRedis(Long cacheId,Long id){
        String key=CONTACTS_REQUEST_KEY+cacheId;
        String contactRequestJson=stringRedisTemplate.opsForValue ().get (key);
        List<User> contactRequestList=JSONUtil.toList (contactRequestJson,User.class);
        //查看是否已存在该好友请求
        for(User contactRequest:contactRequestList){
            if(contactRequest.getId ()==id){
                return Result.fail ("你已经发送过好友请求了");
            }
        }
        //不存在,添加到好友请求中
        //从数据查询
        User user=userMapper.selectById (id);
        contactRequestList.add (user);
        //写入redis
        stringRedisTemplate.opsForValue ().set (key,JSONUtil.toJsonStr (contactRequestList));
        return Result.ok ();
    }
    //删除好友请求到redis方法
    private Result delContactRequestByRedis(Long mineId,Long id){
        String key=CONTACTS_REQUEST_KEY+mineId;
        String contactRequestJson=stringRedisTemplate.opsForValue ().get (key);
        List<User> contactRequestList=JSONUtil.toList (contactRequestJson,User.class);
        for(User user:contactRequestList){
            if(user.getId ()==id){
                contactRequestList.remove (user);
                break;
            }
        }
        stringRedisTemplate.opsForValue ().set (key,JSONUtil.toJsonStr (contactRequestList));
        return Result.ok ();

    }
    @Override
    public Result disagreeRequest(Long id) {
        UserDTO me=UserHolder.getUser ();
        //从redis删除该请求
        Result result=delContactRequestByRedis (me.getId (), id);
        if(!result.isSuccess ()){
            return result;
        }
        //发送邮件通知目标用户被拒绝
        Mail mail=new Mail (me.getId (),id,me.getUsername ()+"拒绝了你的好友请求",LocalDateTime.now ());
        mailService.send (mail);
        return Result.ok ();
    }
    @Transactional
    public void saveRelationOnBoth(Long mineid,Long id){
        Long relationKey= RandomUtil.randomLong (1000L,1000000000L);
        userMapper.saveUserRelation (mineid,id,relationKey);
        userMapper.saveUserRelation (id,mineid,relationKey);
    }

}
